﻿namespace OpenAdmin.Application.Services;

/// <summary>
/// 
/// </summary>
public class RoleService : ServiceBase, IRoleService, ITransientDependency
{
    private readonly IRepository<SysUser, ApplicationDbContextLocator> _userRepository;
    private readonly IRepository<SysRole, ApplicationDbContextLocator> _roleRepository;
    private readonly IRepository<SysUserRole, ApplicationDbContextLocator> _userRoleRepository;
    /// <summary>
    /// ctor
    /// </summary>
    /// <param name="userRepository"></param>
    /// <param name="roleRepository"></param>
    /// <param name="userRoleRepository"></param>
    public RoleService(IRepository<SysUser, ApplicationDbContextLocator> userRepository,
        IRepository<SysRole, ApplicationDbContextLocator> roleRepository,
        IRepository<SysUserRole, ApplicationDbContextLocator> userRoleRepository)
    {
        _userRepository = userRepository;
        _roleRepository = roleRepository;
        _userRoleRepository = userRoleRepository;
    }

    /// <summary>
    /// 获取角色列表
    /// </summary>
    /// <returns></returns>
    public async Task<List<RoleResponseDto>> GetRoles(string keyworld = default)
    {
        var roleQueryable = _roleRepository.Entities.AsQueryable().Where(p => p.Enabled == true);
        if (!string.IsNullOrWhiteSpace(keyworld))
        {
            roleQueryable = roleQueryable.Where(p => p.Name.Contains(keyworld));
        }

        var roles = await roleQueryable.ProjectToType<RoleResponseDto>().ToListAsync();

        return roles;
    }

    /// <summary>
    /// 分页获取角色列表
    /// </summary>
    /// <param name="requestDto"></param>
    /// <returns></returns>
    public async Task<PagedList<RolesByPageResponseDto>> GetRolesByPage(RolesByPageRequestDto requestDto)
    {
        var roleQueryable = _roleRepository.Entities.AsQueryable();
        if (!string.IsNullOrWhiteSpace(requestDto.Keyworld))
        {
            roleQueryable = roleQueryable.Where(p => p.Name.Contains(requestDto.Keyworld));
        }
        var pagedList = await roleQueryable.ProjectToType<RolesByPageResponseDto>()
            .ToPagedListAsync(p => p.CreateTime, requestDto.PageIndex, requestDto.PageSize);

        return pagedList;
    }

    /// <summary>
    /// 根据用户获取角色列表
    /// </summary>
    /// <param name="userId"></param>
    /// <returns></returns>
    public async Task<List<RoleResponseDto>> GetRolesByUserId(int[] userId)
    {
        var roles = await (from r in _roleRepository.Entities
                           join ur in _userRoleRepository.Entities on r.Id equals ur.RoleId
                           join u in _userRepository.Entities on ur.UserId equals u.Id
                           where userId.Contains(u.Id) && r.Enabled == true
                           select new RoleResponseDto
                           {
                               Id = r.Id,
                               Name = r.Name,
                               Enabled = r.Enabled,
                               CreateBy = r.CreateBy,
                               CreateTime = r.CreateTime,
                               ModifyBy = r.ModifyBy,
                               ModifyTime = r.ModifyTime,
                               Remark = r.Remark,
                               UserId = u.Id
                           })
                           .ToListAsync();

        return roles;
    }

    /// <summary>
    /// 添加角色
    /// </summary>
    /// <param name="requestDto"></param>
    /// <returns></returns>
    public async Task AddRole(AddRoleRequestDto requestDto)
    {
        var role = await _roleRepository.Entities.SingleOrDefaultAsync(p => p.Name == requestDto.Name);
        role.ThrowIf(p => p != null, "该角色已存在");

        role = _mapper.Map<SysRole>(requestDto);
        role.CreateTime = DateTime.Now;
        role.Enabled = true;
        role.CreateBy = UserIdentity.UserId;
        _roleRepository.Entities.Add(role);

        var result = await _roleRepository.SaveChangesAsync();
        result.ThrowIf(p => p == 0, "添加角色失败");
    }

    /// <summary>
    /// 更新角色信息
    /// </summary>
    /// <param name="requestDto"></param>
    public async Task EditRole(EditRoleRequestDto requestDto)
    {
        var role = await _roleRepository.Entities.FindAsync(requestDto.Id);
        role.ThrowIf(p => p == null, "该角色不存在");

        role.Name = requestDto.Name;
        role.Remark = requestDto.Remark;
        role.Enabled = requestDto.Enabled;
        role.ModifyBy = UserIdentity.UserId;

        var uResult = await _roleRepository.SaveChangesAsync();
        uResult.ThrowIf(p => p == 0, "更新角色信息失败");
    }

    /// <summary>
    /// 删除角色
    /// </summary>
    /// <param name="id"></param>
    public async Task DeleteRole(int id)
    {
        var role = await _roleRepository.Entities.FindAsync(id);
        role.ThrowIf(p => p == null, "该角色不存在");

        role.IsDeleted = true;
        var dResult = await _roleRepository.SaveChangesAsync();
        dResult.ThrowIf(p => p == 0, "删除角色失败");
    }
}
